#include <QProcess>

#include "mplayercontroller.h"

#ifdef Q_WS_WIN
    #define MPLAYER_PATH "E:\\MPlayer_Windows\\mplayer\\mplayer_core.exe"
#else
    #define MPLAYER_PATH "/bin/mplayer"
#endif

MPlayerController::MPlayerController(QObject *parent)
    :QObject(parent),currentState(DefaultState)
{
    mplayerProcess = new QProcess(this);

    connect(mplayerProcess, SIGNAL(readyReadStandardOutput()),
        this, SLOT(catchMPlayerOutput()));

    connect(mplayerProcess, SIGNAL(finished(int, QProcess::ExitStatus)),
        this, SLOT(mediaEnd(int, QProcess::ExitStatus)));
}

void MPlayerController::catchMPlayerOutput()
{
    while(mplayerProcess->canReadLine())
    {
        QByteArray buffer(mplayerProcess->readLine());
        // get_time_length : ANS_LENGTH=xx.yy
        if(buffer.startsWith("ANS_LENGTH"))
        {
            buffer.remove(0, 11); // vire ANS_LENGTH=
            buffer.replace(QByteArray("'"), QByteArray(""));
            buffer.replace(QByteArray(" "), QByteArray(""));
            buffer.replace(QByteArray("\n"), QByteArray(""));
            buffer.replace(QByteArray("\r"), QByteArray(""));
            float maxTime = buffer.toFloat();
            emit totalTimeReceived(static_cast<int>(maxTime + 1));
        }
        // get_time_pos : ANS_TIME_POSITION=xx.y
        else if(buffer.startsWith("ANS_TIME_POSITION"))
        {
            buffer.remove(0, 18); // vire ANS_TIME_POSITION=
            buffer.replace(QByteArray("'"), QByteArray(""));
            buffer.replace(QByteArray(" "), QByteArray(""));
            buffer.replace(QByteArray("\n"), QByteArray(""));
            buffer.replace(QByteArray("\r"), QByteArray(""));
            float currentTime = buffer.toFloat();
            emit currentTimePositionReceived(static_cast<int>(currentTime + 1));
        }
    }

}
bool MPlayerController::requestCurrentTimePosition()
{
    mplayerProcess->write("get_time_pos\n");
    return true;
}

bool MPlayerController::startMPlayer(QString szPath, QRect playerRect, int position,int volume)
{
    QStringList args;
#ifndef Q_WS_WIN
    args << "-framebuffer-index" << "1";
    args << "-videoframe" << "fullscreen:keepratio";
    QString screenRect = QString("%1,%2,%3,%4")
            .arg(playerRect.left())
            .arg(playerRect.top())
            .arg(playerRect.width())
            .arg(playerRect.height());
    args << "-screenrect";
    args << screenRect;
#endif

#ifdef Q_WS_WIN
    args << "-volume" << QString::number(volume);
#endif

#ifndef Q_WS_WIN
    args << "-tvout" << "tvandlcd";
#endif
    args << "-slave";
    args << "-quiet";

    args << szPath;

    mplayerProcess->setProcessChannelMode(QProcess::MergedChannels);
    mplayerProcess->start(MPLAYER_PATH, args);
    if(mplayerProcess->waitForStarted())
    {
        setCurrentState(PlayingState);
    }
    else
    {
        qDebug("startMplayer failed");
        return false;
    }
    mplayerProcess->write("get_video_resolution\n");
    mplayerProcess->write("get_time_length\n");
    if (position > 0)
    {
         mplayerProcess->write(QString("seek  %1 2\n").arg(position).toUtf8());
    }
#ifndef Q_WS_WIN
    setVolume(volume);
#endif
    return true;
}

bool MPlayerController::stopMPlayer()
{
    bool result = false;
    if(getCurrentState() != PlayingState)
    {
        result = true;
    }
    else
    {
        mplayerProcess->write("quit\n");
        if(mplayerProcess->waitForFinished())
        {
            setCurrentState(StoppedState);
            result = true;
        }
        else
        {
            setCurrentState(ErrorState);
            result = false;
        }
    }
    return result;
}

bool MPlayerController::playOrPauseMPlayer()
{
    mplayerProcess->write("pause\n");
    if(currentState == PlayingState)
    {
        setCurrentState(PausedState);
    }
    else if(currentState == PausedState)
    {
        setCurrentState(PlayingState);
    }
    emit stateChanged(currentState);
    return true;
}

enum MPlayerController::State MPlayerController::getCurrentState()
{
    return currentState;
}

void MPlayerController::setCurrentState(enum MPlayerController::State state)
{
    currentState = state;
    emit stateChanged(currentState);
}

void MPlayerController::seek(int sec)
{
    if ( (mplayerProcess != NULL ) && ( sec >= 0) )
    {
        mplayerProcess->write(QString("seek  %1 2\n").arg(sec).toUtf8());
        setCurrentState(PlayingState);
    }
}
void MPlayerController::mediaEnd(int, QProcess::ExitStatus)
{
    setCurrentState(StoppedState);
}

void MPlayerController::setVolume(int volume)
{
    if(volume >= 0 && volume <= 100)
    {
        mplayerProcess->write(QString("volume %1 2\n").arg(volume).toUtf8());
    }
}

MPlayerController::~MPlayerController()
{
    stopMPlayer();
}
